using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Authorization;
using Microsoft.Extensions.Logging;
using JGSY.CMS.LowCode.Platform.Application.DTOs;
using JGSY.CMS.LowCode.Platform.Application.Interfaces;
using System.ComponentModel.DataAnnotations;

namespace JGSY.CMS.LowCode.Platform.Controllers
{
    /// <summary>
    /// 模板管理控制器
    /// </summary>
    /// <remarks>
    /// <para>功能概述：</para>
    /// <list type="bullet">
    /// <item><description>提供模板的完整生命周期管理</description></item>
    /// <item><description>支持模板的创建、编辑、删除和查询操作</description></item>
    /// <item><description>实现模板版本控制和状态管理</description></item>
    /// <item><description>提供模板分类和标签管理</description></item>
    /// </list>
    /// 
    /// <para>业务场景：</para>
    /// <list type="bullet">
    /// <item><description>低代码平台的页面模板管理</description></item>
    /// <item><description>内容管理系统的展示模板</description></item>
    /// <item><description>工作流程模板的定义和应用</description></item>
    /// <item><description>表单模板的设计和复用</description></item>
    /// </list>
    /// 
    /// <para>权限控制：</para>
    /// <list type="bullet">
    /// <item><description>所有操作需要用户身份验证</description></item>
    /// <item><description>部分管理操作需要特定角色权限</description></item>
    /// <item><description>支持模板级别的访问控制</description></item>
    /// </list>
    /// </remarks>
    [ApiController]
    [Route("api/[controller]")]
    [Authorize]
    public class TemplatesController : ControllerBase
    {
        private readonly ITemplateAppService _templateService;
        private readonly ILogger<TemplatesController> _logger;

        public TemplatesController(ITemplateAppService templateService, ILogger<TemplatesController> logger)
        {
            _templateService = templateService;
            _logger = logger;
        }

        /// <summary>
        /// 获取分页模板列表
        /// </summary>
        /// <param name="query">分页查询参数，包含页码、页大小、搜索关键词等</param>
        /// <returns>分页模板结果集</returns>
        /// <remarks>
        /// <para>功能说明：</para>
        /// <list type="bullet">
        /// <item><description>支持分页查询，避免大量数据一次性加载</description></item>
        /// <item><description>提供关键词搜索功能，支持模糊匹配</description></item>
        /// <item><description>支持按创建时间、更新时间等字段排序</description></item>
        /// <item><description>返回模板基本信息和统计数据</description></item>
        /// </list>
        /// 
        /// <para>查询参数：</para>
        /// <list type="bullet">
        /// <item><description>PageIndex: 页码，从1开始</description></item>
        /// <item><description>PageSize: 页大小，建议10-50之间</description></item>
        /// <item><description>Keyword: 搜索关键词，支持模板名称和描述</description></item>
        /// <item><description>SortBy: 排序字段</description></item>
        /// </list>
        /// </remarks>
        /// <response code="200">查询成功，返回分页结果</response>
        /// <response code="400">查询参数无效</response>
        /// <response code="401">未授权访问</response>
        /// <response code="500">服务器内部错误</response>
        [HttpGet]
        public async Task<ActionResult<PagedResultDto<TemplateDto>>> GetPagedList([FromQuery] PagedQueryDto query)
        {
            try
            {
                var result = await _templateService.GetPagedListAsync(query);
                return Ok(result);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "获取模板列表失败");
                return StatusCode(500, new { message = "获取模板列表失败", error = ex.Message });
            }
        }

        /// <summary>
        /// 根据ID获取模板详情
        /// </summary>
        /// <param name="id">模板的唯一标识符</param>
        /// <returns>模板详细信息</returns>
        /// <remarks>
        /// <para>功能说明：</para>
        /// <list type="bullet">
        /// <item><description>获取指定ID的模板完整信息</description></item>
        /// <item><description>包含模板内容、配置参数和元数据</description></item>
        /// <item><description>返回模板的最新版本信息</description></item>
        /// <item><description>自动记录模板访问日志</description></item>
        /// </list>
        /// 
        /// <para>返回内容：</para>
        /// <list type="bullet">
        /// <item><description>模板基本信息：名称、描述、类型</description></item>
        /// <item><description>模板内容：HTML、CSS、JavaScript代码</description></item>
        /// <item><description>配置数据：参数定义、默认值</description></item>
        /// <item><description>状态信息：版本、状态、创建时间</description></item>
        /// </list>
        /// </remarks>
        /// <response code="200">查询成功，返回模板详情</response>
        /// <response code="404">模板不存在</response>
        /// <response code="401">未授权访问</response>
        /// <response code="500">服务器内部错误</response>
        [HttpGet("{id}")]
        public async Task<ActionResult<TemplateDto>> GetById(long id)
        {
            try
            {
                var template = await _templateService.GetByIdAsync(id);
                if (template == null)
                {
                    return NotFound(new { message = $"模板不存在: {id}" });
                }
                return Ok(template);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "获取模板详情失败: {Id}", id);
                return StatusCode(500, new { message = "获取模板详情失败", error = ex.Message });
            }
        }

        /// <summary>
        /// 根据名称获取模板
        /// </summary>
        /// <param name="name">模板名称</param>
        /// <returns>匹配名称的模板信息</returns>
        /// <remarks>
        /// <para>功能说明：</para>
        /// <list type="bullet">
        /// <item><description>通过模板名称进行精确匹配查找</description></item>
        /// <item><description>模板名称在系统中具有唯一性</description></item>
        /// <item><description>支持区分大小写的名称匹配</description></item>
        /// <item><description>返回完整的模板信息</description></item>
        /// </list>
        /// 
        /// <para>使用场景：</para>
        /// <list type="bullet">
        /// <item><description>通过已知模板名称快速定位</description></item>
        /// <item><description>API集成时的模板引用</description></item>
        /// <item><description>模板继承和引用关系处理</description></item>
        /// </list>
        /// </remarks>
        /// <response code="200">查询成功，返回模板信息</response>
        /// <response code="404">指定名称的模板不存在</response>
        /// <response code="401">未授权访问</response>
        /// <response code="500">服务器内部错误</response>
        [HttpGet("by-name/{name}")]
        public async Task<ActionResult<TemplateDto>> GetByName(string name)
        {
            try
            {
                var template = await _templateService.GetByNameAsync(name);
                if (template == null)
                {
                    return NotFound(new { message = $"模板不存在: {name}" });
                }
                return Ok(template);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "根据名称获取模板失败: {Name}", name);
                return StatusCode(500, new { message = "获取模板失败", error = ex.Message });
            }
        }

        /// <summary>
        /// 根据类型获取模板列表
        /// </summary>
        /// <param name="type">模板类型</param>
        /// <returns>指定类型的模板列表</returns>
        /// <remarks>
        /// <para>功能说明：</para>
        /// <list type="bullet">
        /// <item><description>按模板类型分类查询</description></item>
        /// <item><description>支持多种模板类型：页面模板、表单模板、报表模板等</description></item>
        /// <item><description>返回该类型下的所有可用模板</description></item>
        /// <item><description>按创建时间倒序排列</description></item>
        /// </list>
        /// 
        /// <para>模板类型：</para>
        /// <list type="bullet">
        /// <item><description>page: 页面展示模板</description></item>
        /// <item><description>form: 表单输入模板</description></item>
        /// <item><description>report: 报表展示模板</description></item>
        /// <item><description>email: 邮件通知模板</description></item>
        /// </list>
        /// </remarks>
        /// <response code="200">查询成功，返回模板列表</response>
        /// <response code="400">模板类型无效</response>
        /// <response code="401">未授权访问</response>
        /// <response code="500">服务器内部错误</response>
        [HttpGet("by-type/{type}")]
        public async Task<ActionResult<List<TemplateDto>>> GetByType(string type)
        {
            try
            {
                var templates = await _templateService.GetByTypeAsync(type);
                return Ok(templates);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "根据类型获取模板失败: {Type}", type);
                return StatusCode(500, new { message = "获取模板失败", error = ex.Message });
            }
        }

        /// <summary>
        /// 获取默认模板
        /// </summary>
        [HttpGet("default/{type}")]
        public async Task<ActionResult<TemplateDto>> GetDefault(string type)
        {
            try
            {
                var template = await _templateService.GetDefaultAsync(type);
                if (template == null)
                {
                    return NotFound(new { message = $"未找到类型为 {type} 的默认模板" });
                }
                return Ok(template);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "获取默认模板失败: {Type}", type);
                return StatusCode(500, new { message = "获取默认模板失败", error = ex.Message });
            }
        }

        /// <summary>
        /// 创建新模板
        /// </summary>
        /// <param name="dto">模板数据传输对象</param>
        /// <returns>创建成功的模板信息</returns>
        /// <remarks>
        /// <para>功能说明：</para>
        /// <list type="bullet">
        /// <item><description>创建新的模板并保存到数据库</description></item>
        /// <item><description>自动验证模板数据的完整性和有效性</description></item>
        /// <item><description>支持模板内容的语法检查</description></item>
        /// <item><description>自动生成模板版本号</description></item>
        /// </list>
        /// 
        /// <para>必填字段：</para>
        /// <list type="bullet">
        /// <item><description>Name: 模板名称，系统内唯一</description></item>
        /// <item><description>Type: 模板类型</description></item>
        /// <item><description>Content: 模板内容</description></item>
        /// <item><description>Description: 模板描述</description></item>
        /// </list>
        /// 
        /// <para>业务规则：</para>
        /// <list type="bullet">
        /// <item><description>模板名称不能重复</description></item>
        /// <item><description>模板内容必须符合语法规范</description></item>
        /// <item><description>创建后默认为草稿状态</description></item>
        /// </list>
        /// </remarks>
        /// <response code="201">模板创建成功，返回Location头指向新资源</response>
        /// <response code="400">请求数据无效或模板名称重复</response>
        /// <response code="401">未授权访问</response>
        /// <response code="500">服务器内部错误</response>
        [HttpPost]
        public async Task<ActionResult<TemplateDto>> Create([FromBody] TemplateDto dto)
        {
            try
            {
                if (!ModelState.IsValid)
                {
                    return BadRequest(ModelState);
                }

                var template = await _templateService.CreateAsync(dto);
                return CreatedAtAction(nameof(GetById), new { id = template.Id }, template);
            }
            catch (ArgumentException ex)
            {
                return BadRequest(new { message = ex.Message });
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "创建模板失败");
                return StatusCode(500, new { message = "创建模板失败", error = ex.Message });
            }
        }

        /// <summary>
        /// 更新模板
        /// </summary>
        [HttpPut("{id}")]
        public async Task<ActionResult<TemplateDto>> Update(long id, [FromBody] TemplateDto dto)
        {
            try
            {
                if (!ModelState.IsValid)
                {
                    return BadRequest(ModelState);
                }

                var template = await _templateService.UpdateAsync(id, dto);
                return Ok(template);
            }
            catch (ArgumentException ex)
            {
                return BadRequest(new { message = ex.Message });
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "更新模板失败: {Id}", id);
                return StatusCode(500, new { message = "更新模板失败", error = ex.Message });
            }
        }

        /// <summary>
        /// 删除模板
        /// </summary>
        [HttpDelete("{id}")]
        public async Task<IActionResult> Delete(long id)
        {
            try
            {
                var success = await _templateService.DeleteAsync(id);
                if (!success)
                {
                    return NotFound(new { message = $"模板不存在: {id}" });
                }
                return NoContent();
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "删除模板失败: {Id}", id);
                return StatusCode(500, new { message = "删除模板失败", error = ex.Message });
            }
        }

        /// <summary>
        /// 批量删除模板
        /// </summary>
        [HttpPost("batch-delete")]
        public async Task<IActionResult> BatchDelete([FromBody] JGSY.CMS.LowCode.Platform.Application.DTOs.BatchDeleteRequest request)
        {
            try
            {
                if (request?.Ids == null || !request.Ids.Any())
                {
                    return BadRequest(new { message = "请选择要删除的模板" });
                }

                var success = await _templateService.BatchDeleteAsync(request.Ids);
                return Ok(new { message = $"成功删除 {success} 个模板" });
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "批量删除模板失败");
                return StatusCode(500, new { message = "批量删除模板失败", error = ex.Message });
            }
        }

        /// <summary>
        /// 渲染模板
        /// </summary>
        [HttpPost("{id}/render")]
        public async Task<ActionResult<string>> Render(long id, [FromBody] object data)
        {
            try
            {
                var result = await _templateService.RenderAsync(id, data);
                return Ok(new { result });
            }
            catch (ArgumentException ex)
            {
                return BadRequest(new { message = ex.Message });
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "渲染模板失败: {Id}", id);
                return StatusCode(500, new { message = "渲染模板失败", error = ex.Message });
            }
        }

        /// <summary>
        /// 渲染模板内容
        /// </summary>
        [HttpPost("render-content")]
        public async Task<ActionResult<string>> RenderContent([FromBody] JGSY.CMS.LowCode.Platform.Application.DTOs.RenderContentRequest request)
        {
            try
            {
                if (string.IsNullOrWhiteSpace(request.Content))
                {
                    return BadRequest(new { message = "模板内容不能为空" });
                }

                var result = await _templateService.RenderContentAsync(request.Content, request.Data ?? new object(), request.Engine ?? "razor");
                return Ok(new { result });
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "渲染模板内容失败");
                return StatusCode(500, new { message = "渲染模板内容失败", error = ex.Message });
            }
        }

        /// <summary>
        /// 预览模板
        /// </summary>
        [HttpPost("{id}/preview")]
        public async Task<ActionResult<string>> Preview(long id, [FromBody] object? data = null)
        {
            try
            {
                var result = await _templateService.PreviewAsync(id, data);
                return Ok(new { result });
            }
            catch (ArgumentException ex)
            {
                return BadRequest(new { message = ex.Message });
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "预览模板失败: {Id}", id);
                return StatusCode(500, new { message = "预览模板失败", error = ex.Message });
            }
        }

        /// <summary>
        /// 验证模板
        /// </summary>
        [HttpPost("validate")]
        public async Task<ActionResult> Validate([FromBody] JGSY.CMS.LowCode.Platform.Application.DTOs.ValidateTemplateRequest request)
        {
            try
            {
                if (string.IsNullOrWhiteSpace(request.Content))
                {
                    return BadRequest(new { message = "模板内容不能为空" });
                }

                var result = await _templateService.ValidateAsync(request.Content, request.Engine ?? "razor");
                return Ok(new 
                { 
                    isValid = result.IsValid,
                    errors = result.Errors 
                });
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "验证模板失败");
                return StatusCode(500, new { message = "验证模板失败", error = ex.Message });
            }
        }

        /// <summary>
        /// 复制模板
        /// </summary>
        [HttpPost("{id}/copy")]
        public async Task<ActionResult<TemplateDto>> Copy(long id, [FromBody] JGSY.CMS.LowCode.Platform.Application.DTOs.CopyTemplateRequest request)
        {
            try
            {
                if (string.IsNullOrWhiteSpace(request.NewName))
                {
                    return BadRequest(new { message = "新模板名称不能为空" });
                }

                var template = await _templateService.CopyAsync(id, request.NewName);
                return CreatedAtAction(nameof(GetById), new { id = template.Id }, template);
            }
            catch (ArgumentException ex)
            {
                return BadRequest(new { message = ex.Message });
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "复制模板失败: {Id}", id);
                return StatusCode(500, new { message = "复制模板失败", error = ex.Message });
            }
        }

        /// <summary>
        /// 设置启用/禁用状态
        /// </summary>
        [HttpPut("{id}/enabled")]
        public async Task<IActionResult> SetEnabled(long id, [FromBody] JGSY.CMS.LowCode.Platform.Application.DTOs.SetEnabledRequest request)
        {
            try
            {
                var success = await _templateService.SetEnabledAsync(id, request.Enabled);
                if (!success)
                {
                    return NotFound(new { message = $"模板不存在: {id}" });
                }
                return Ok(new { message = $"模板已{(request.Enabled ? "启用" : "禁用")}" });
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "设置模板状态失败: {Id}", id);
                return StatusCode(500, new { message = "设置模板状态失败", error = ex.Message });
            }
        }

        /// <summary>
        /// 设置为默认模板
        /// </summary>
        [HttpPut("{id}/set-default")]
        public async Task<IActionResult> SetDefault(long id)
        {
            try
            {
                var success = await _templateService.SetDefaultAsync(id);
                if (!success)
                {
                    return NotFound(new { message = $"模板不存在: {id}" });
                }
                return Ok(new { message = "已设置为默认模板" });
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "设置默认模板失败: {Id}", id);
                return StatusCode(500, new { message = "设置默认模板失败", error = ex.Message });
            }
        }

        /// <summary>
        /// 获取模板变量
        /// </summary>
        [HttpGet("{id}/variables")]
        public async Task<ActionResult<Dictionary<string, object>>> GetVariables(long id)
        {
            try
            {
                var variables = await _templateService.GetVariablesAsync(id);
                return Ok(variables);
            }
            catch (ArgumentException ex)
            {
                return BadRequest(new { message = ex.Message });
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "获取模板变量失败: {Id}", id);
                return StatusCode(500, new { message = "获取模板变量失败", error = ex.Message });
            }
        }

        /// <summary>
        /// 导出模板
        /// </summary>
        [HttpPost("export")]
        public async Task<IActionResult> Export([FromBody] JGSY.CMS.LowCode.Platform.Application.DTOs.ExportTemplatesRequest request)
        {
            try
            {
                if (request?.Ids == null || !request.Ids.Any())
                {
                    return BadRequest(new { message = "请选择要导出的模板" });
                }

                var data = await _templateService.ExportAsync(request.Ids);
                return File(data, "application/json", "templates.json");
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "导出模板失败");
                return StatusCode(500, new { message = "导出模板失败", error = ex.Message });
            }
        }

        /// <summary>
        /// 导入模板
        /// </summary>
        [HttpPost("import")]
        public async Task<ActionResult<List<TemplateDto>>> Import(IFormFile file)
        {
            try
            {
                if (file == null || file.Length == 0)
                {
                    return BadRequest(new { message = "请选择要导入的文件" });
                }

                using var stream = new MemoryStream();
                await file.CopyToAsync(stream);
                var data = stream.ToArray();

                var templates = await _templateService.ImportAsync(data);
                return Ok(templates);
            }
            catch (Exception ex)
            {
                _logger.LogError(ex, "导入模板失败");
                return StatusCode(500, new { message = "导入模板失败", error = ex.Message });
            }
        }
    }
}
